const webpack = require('webpack')

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
// const TerserWebpackPlugin = require('terser-webpack-plugin')

// 注意：thread-loader 只处理耗时构建任务，且存在一定限制
const threadLoader = require('thread-loader');
threadLoader.warmup(
    {
      // 池选项，例如传递给 loader 选项
      // 必须匹配 loader 选项才能启动正确的池
    },
    [
      // 可以是任意模块，例如
      'babel-loader',
    ]
);

module.exports = {
    entry: {
        index: './src/pages/index/index.js',
        album: './src/pages/album/album.js',
        work: './src/pages/work/work.js'
    },
    output: {
        // filename: '[name].bundle.js',
        filename: '[name]-[contenthash:8].bundle.js',// contenthash:8最常用，用于避免缓存问题
        path: path.join(__dirname, 'dist'),
        // publicPath: 'dist/'                          // 告诉webpack，生成的文件在哪个目录
    },
    // stats: 'errors-warnings',
    resolve: {
        alias: {
          "@": path.resolve(__dirname, 'src//')       // 路径别名，让import引入变得简单
        }
    },
    // 1、optimization中：自动提取所有公共模块到单独 bundle
    // 2、optimization中：开发阶段手动打开代码压缩，默认自动压缩js
    // 3、optimization中：tree-shaking，开发阶段一般不打开，生产自动打开
    optimization: {
        // splitChunks取代了webpack4中的CommonsChunkPlugin
        splitChunks: {  
            // 1、自动提取所有公共模块到单独 bundle，可选配置有：all，async 和 initial。
            // 设置为 all 可能特别强大，因为这意味着 chunk 可以在异步和非异步 chunk 之间共享
            chunks: 'all',
            automaticNameDelimiter: '-'
        },
        // 2、开发阶段手动打开代码压缩，默认自动压缩js
        // minimizer: [                            // 使用了minimizer，webpack认为不再启动自动压缩js代码
        //   new TerserWebpackPlugin(),            // 手动打开js压缩代码
        //   new OptimizeCssAssetsWebpackPlugin()  // 手动打开css压缩代码
        // ]
    },
    // // 3、tree-shaking，开发阶段一般不打开，生产自动打开
    // optimization: {
    //     // 模块只导出被使用的成员
    //     usedExports: true,
    //     // 压缩输出结果，usedExports开启后会移除未被使用的成员
    //     minimize: true,
    //     // 尽可能合并每一个模块到一个函数中（Scop Hosting）
    //     concatenateModules: true,
    // }
    devtool: 'eval-cheap-module-source-map',       // 开发模式：cheap-module-eval-source-map，生产模式：none
    module: {
        rules: [
            {// 转换js代码，es6+=>es5
                test: /\.js$/,
                exclude: /node_modules/,
                use: 'thread-loader',
                // use: 'babel-loader'
                // use: {
                //     loader: 'babel-loader',
                //     options: {
                //         presets: ['@babel/preset-env']
                //     }                        // babel的配置信息可以放到.babelrc或者babel.config.js
                // }
            },
            {// css样式文件的加载
                test: /\.css$/,                  // 匹配文件
                use: [                           // use指定使用到的loader
                    // 'style-loader',           // 将css-loader转换后的结果放到style标签里面
                    MiniCssExtractPlugin.loader, // 将样式存放到单独的css文件中，取代style-loader
                    'css-loader'                 // 先执行css-loader，而且是从后往前执行，所以需要放到下面 
                ]
            },
            // {// 将图片文件复制到另一个目录      // url-loader 和 file-loader只使用一个就行
            //     test: /\.(png|svg|jpg|gif)$/,
            //     use: {
            //         loader: 'file-loader',
            //         options: {
            //             name: '[name]-[contenthash:8].[ext]',
            //             outputPath: 'images',
            //             esModule: false        // 新版loader需要配置，否则会产生错误：img src=[object Module]
            //         },
            //     }
            // },
            {// 将图片编码成base64
                test: /\.(png|svg|jpg|gif)$/,
                use: {
                    loader: 'url-loader',         // url-loader对file-loader有依赖，需要提前安装
                    options: {
                        name: '[name]-[contenthash:8].[ext]',
                        outputPath: 'images',
                        limit: 10 * 1024,         // 10 KB 对文件大小进行限制，超过就不转换
                        esModule: false           // 新版loader需要配置，否则会产生错误：img src=[object Module]
                    },
                }
            },
            // {
            //     test: /\.html$/,
            //     use: {
            //         loader: 'html-loader',
            //         options: {
            //             attrs: ['img:src', 'a:href']   // 配置img的src，a的href引用的资源都打包进项目
            //         }
            //     }
            // }
        ]
    },
    plugins: [
        // new CleanWebpackPlugin(),
        // 用于生成 index.html
        new HtmlWebpackPlugin({
            title: 'index首页',
            meta: {
                viewport: 'width=device-width'
            },
            minify: {
                removeAttributeQuotes: true     // 移除属性的引号
            },
            inject: true,                       // script是否至于body底部
            template: './src/pages/index/index.html',
            filename: 'index.html',
            // cache: false,
            chunks: ['index'],                  // 指定加载js文件，默认全部加载
            // showErrors: true,                // 如果 webpack 编译出现错误，webpack会将错误信息包裹在一个 pre 标签内，属性的默认值为 true ，也就是显示错误信息。
        }),
        new HtmlWebpackPlugin({
            title: 'about首页',
            template: './src/pages/album/album.html',
            filename: 'album.html',
            chunks: ['album'],                  // 指定加载js文件，默认全部加载
        }),
        new HtmlWebpackPlugin({
            title: 'work首页',
            template: './src/pages/work/work.html',
            filename: 'work.html',
            chunks: ['work'],                   // 指定加载js文件，默认全部加载
        }),
        new MiniCssExtractPlugin()              // 提取样式到css文件

        // 拷贝文件 => 开发阶段最好不要使用这个插件，提升构建速度
        // new CopyWebpackPlugin(['public'])
        // 模块热更新
        // new webpack.HotModuleReplacementPlugin()
    ]
}



// 遗留问题：
// 1、未自动刷新浏览器 watch配置项的位置 —— ok，webpack5的问题
// 2、按需加载模块 —— ok
// 3、关于路径配置问题 —— 待梳理
// 4、提取公共代码 —— ok
// 5、路径别名貌似有些小问题，webpack5
// 6、实践中，本地开发devserver生成文件是在浏览器内存；所以最佳实践是怎样的？？——ok，参考文档
// 7、auto-web-plugin插件按照目录生成html